package com.toraeve.asktora.daoimpl;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import com.toraeve.asktora.daoimpl.mapper.UserMapper;
import com.toraeve.asktora.domain.entity.ToraUser;
import com.toraeve.asktora.domain.repository.UserRepository;

@Repository
public class UserRepositoryImpl implements UserRepository {

	private static Log logger = LogFactory.getLog(UserRepositoryImpl.class);
	private UserMapper userMapper;

	@Autowired
	@Required
	public void setUserMapper(UserMapper userMapper) {
		Assert.notNull(userMapper, "UserMapper cannot be null!");
		this.userMapper = userMapper;
	}

	@Override
	public ToraUser getUserByEmail(String userEmail) {
		Assert.notNull(userEmail, "argument:[userEmail] cannot be null!");
		logger.debug("Tring to get user with email:" + userEmail);
		ToraUser user = null;
		try {
			user = userMapper.getUserByEmail(userEmail);
		} catch (RuntimeException e) {
			logger.error("Exception threw while getting user with email:"
					+ userEmail, e);
			throw e;
		}
		logger.debug("Returning user:" + user);
		return user;
	}

	@Override
	public void addUser(ToraUser newUser) {
		Assert.notNull(newUser, "argument:[newUser] cannot be null!");
		logger.debug("Tring to add new user:" + newUser);
		try {
			userMapper.addUser(newUser);
		} catch (RuntimeException e) {
			logger.error("Exception threw while adding user:" + newUser, e);
			throw e;
		}
		try {
			Collection<String> roles = newUser.getRole();
			for (String roleName : roles) {
				userMapper.addUserRoleMapping(newUser.getEmail(), roleName);
			}
		} catch (RuntimeException e) {
			logger.error("Exception threw while adding user's role mapping:"
					+ newUser, e);
			throw e;
		}
		logger.debug("New User:" + newUser + " added successfully!");
	}

	@Override
	public void updateUser(ToraUser user) {
		Assert.notNull(user, "argument:[user] cannot be null!");
		logger.debug("Tring to update user:" + user);
		try {
			userMapper.updateUser(user);
		} catch (RuntimeException e) {
			logger.error("Exception threw while updating user:" + user, e);
			throw e;
		}
		try {
			userMapper.deleteUserAllRoleMapping(user.getEmail());
		} catch (RuntimeException e) {
			logger.error(
					"Exception threw while deleting user's all role mapping, user:"
							+ user, e);
			throw e;
		}
		try {
			Collection<String> roles = user.getRole();
			for (String roleName : roles) {
				userMapper.addUserRoleMapping(user.getEmail(), roleName);
			}
		} catch (RuntimeException e) {
			logger.error("Exception threw while update user's role mapping:"
					+ user, e);
			throw e;
		}
		logger.debug("User:" + user + " updated successfully!");
	}

	@Override
	public void deleteUser(String userEmail) {
		Assert.notNull(userEmail, "argument:[userEmail] cannot be null!");
		logger.debug("Tring to delete user with email:" + userEmail);
		try {
			userMapper.markUserDeleted(userEmail);
		} catch (RuntimeException e) {
			logger.error(
					"Exception threw while marking user deleted, user email:"
							+ userEmail, e);
			throw e;
		}
		logger.debug("User with Email:" + userEmail
				+ " marked deleted successfully!");
	}
}
